package BehavioralPattern.Memento;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * @Classname : BeanUtils
 * @Description : 工具类（实现多属性备份）
 * @Author : chentianyu
 * @Date 2023/3/8 21:18
 */


public class BeanUtils {

    /**
     * 把 bean 的所有属性及取值放到 Map 中
     *
     * @param bean
     * @return
     */
    public static Map<String, Object> backupProp(Object bean) {
        Map<String, Object> propMap = new HashMap<>();
        try {
            // 获得Bean描述
            BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());
            // 获得属性描述
            PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
            // 遍历存储所有属性
            for (PropertyDescriptor descriptor : descriptors) {
                // 获取属性名称
                String fieldName = descriptor.getName();
                // 获取属性的get方法
                Method getter = descriptor.getReadMethod();
                // 通过get方法读取属性值
                Object fieldValue = getter.invoke(bean, new Object[]{});
                // 将属性名称和属性值存入Map
                if (!"class".equalsIgnoreCase(fieldName)) {
                    propMap.put(fieldName, fieldValue);
                }
            }
        } catch (Exception e) {
            System.out.println("把 bean 的所有属性及取值放到 Map 过程中出现异常");
        }
        return propMap;
    }


    /**
     * 把 Map 中的值恢复到 bean 中
     *
     * @param bean
     * @param propMap
     */
    public static void restoreProp(Object bean, Map<String, Object> propMap) {
        try {
            // 获得Bean描述
            BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass());
            // 获得属性描述
            PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
            // 遍历存储所有属性
            for (PropertyDescriptor descriptor : descriptors) {
                // 获取属性名称
                String fieldName = descriptor.getName();
                // 若存在该属性，则将值写入 bean
                if (propMap.containsKey(fieldName)) {
                    // 获取属性的set方法
                    Method setter = descriptor.getWriteMethod();
                    // 将值写入 bean
                    setter.invoke(bean, new Object[]{propMap.get(fieldName)});
                }
            }

        } catch (Exception e) {
            System.out.println("把 Map 中的值恢复到 bean 过程中出现异常");
        }
    }

}
